package com.ruowei.modules.foodOrder.web.task;

import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ruowei.modules.foodOrder.domain.QOrder;
import com.ruowei.modules.foodOrder.domain.enumeration.OrderStatus;
import com.ruowei.modules.foodOrder.repository.OrderRepository;
import com.ruowei.modules.foodOrder.service.LifeCycleService;
import com.ruowei.modules.sys.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.time.temporal.ChronoUnit;

@Component
@Slf4j
//处理未支付订单定时任务
public class ProcessingUnpaidOrderTask {

    private final QOrder qOrder = QOrder.order;
    private final JPAQueryFactory jpaQueryFactory;
    private final OrderRepository orderRepository;
    private final RedisUtil redisUtil;
    private final LifeCycleService lifeCycleService;

    public ProcessingUnpaidOrderTask(JPAQueryFactory jpaQueryFactory, OrderRepository orderRepository, RedisUtil redisUtil, LifeCycleService lifeCycleService) {
        this.jpaQueryFactory = jpaQueryFactory;
        this.orderRepository = orderRepository;
        this.redisUtil = redisUtil;
        this.lifeCycleService = lifeCycleService;
    }

    /**
     * @param
     * @apiNote 每5秒执行一次
     * @author 董兴
     * @date 2020-11-10
     */
    //@Scheduled(cron = "*/5 * * * * ?")
    public void processingUnpaidOrder() {
        Instant now = Instant.now();
        jpaQueryFactory.selectFrom(qOrder)
            .where(qOrder.createTime.before(now.minus(15, ChronoUnit.MINUTES))
                .and(qOrder.deleteStatus.eq(false))
                .and(qOrder.status.eq(OrderStatus.TO_BE_PAID)))
            .fetch()
            .forEach(order -> {
                long time = System.currentTimeMillis();
                if (redisUtil.lock(order.getOrderCode(), time)) {
                    order.setStatus(OrderStatus.CANCELLED);
                    order.setUpdateTime(now);
                    orderRepository.saveAndFlush(order);
                    redisUtil.unlock(order.getOrderCode(), time);
                    log.info("订单{}自动取消成功", order.getOrderCode());
                    lifeCycleService.saveLifeCycle(order.getOrderCode(), "", "订单自动取消", "您的订单支付超时，已自动取消", false);
                }
            });
    }
}
